package ru.spbau.krasko.phonelock.main;

import java.util.TimerTask;

import net.rim.device.api.media.MediaActionHandler;
import net.rim.device.api.system.KeyListener;
import net.rim.device.api.ui.Keypad;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.UiEngine;
import net.rim.device.api.ui.input.InputSettings;
import net.rim.device.api.ui.input.TouchscreenSettings;
import ru.spbau.krasko.phonelock.dynamic.DynamicIcon;
import ru.spbau.krasko.phonelock.settings.Settings;

public class LockScreen extends DynamicFieldContainer {
	private BatteryGauge batteryGauge = new BatteryGauge();
	private DateTimeField dateTimeField = new DateTimeField(); 

	private LockScreen() {
	}

	public static final LockScreen INSTANCE = new LockScreen();

	protected boolean trackwheelClick(int status, int time) {
		return true;
	}

	protected boolean navigationClick(int status, int time) {
		return true;
	}

	public boolean onMenu(int instance) {
		return false;
	}

	public boolean onClose() {
		UiApplication.getUiApplication().requestBackground();
		return true;
	}

	// //Magic! Don't touch!
	private final MediaActionHandler soundKeyCapturer = new MediaActionHandler() {
		public boolean mediaAction(int action, int source, Object context) {
			return false;
		}
	};

	private final KeyListener listener = new KeyListener() {
		public boolean keyUp(int keycode, int time) {
			switch (Keypad.key(keycode)) {
			case Keypad.KEY_VOLUME_UP:
			case Keypad.KEY_VOLUME_DOWN:
				GlobalTimerExecutor.INSTANCE.schedule(new TimerTask() {// background and foreground
							// event dispatching
							public void run() { // differs. Without this delay
												// not working in fg.
								UiApplication
										.getUiApplication()
										.addMediaActionHandler(soundKeyCapturer);
							}
						}, 50); // 50 is OK
			case Keypad.KEY_LOCK:
				return false;
			}
			return true;
		}

		public boolean keyStatus(int keycode, int time) {
			return true;
		}

		public boolean keyRepeat(int keycode, int time) {
			switch (Keypad.key(keycode)) {
			case Keypad.KEY_VOLUME_UP:
			case Keypad.KEY_VOLUME_DOWN:
				return false;
			}
			return true;
		}

		public boolean keyDown(int keycode, int time) {
			switch (Keypad.key(keycode)) {
			case Keypad.KEY_VOLUME_UP:
			case Keypad.KEY_VOLUME_DOWN:
				UiApplication.getUiApplication().removeMediaActionHandler(
						soundKeyCapturer);
			case Keypad.KEY_LOCK:
				return false;
			case Keypad.KEY_MIDDLE:
				if (Settings.isEnabled(Settings.ALLOW_CAMERA_KEY)) {
					unlock();
					return false;
				}
			}
			return true;
		}

		public boolean keyChar(char key, int status, int time) {
			return true;
		}
	};
	// //End of magic

	private volatile boolean locked = false;
	private static final InputSettings proximitySettings = TouchscreenSettings
			.createEmptySet();
	static {
		proximitySettings.set(TouchscreenSettings.DETECT_FACE_PROXIMITY, 1);
	}

	public synchronized void lock() {
		if (locked) {
			return;
		}
		DynamicIcon.restoreAll();
		UiApplication app = UiApplication.getUiApplication();
		app.requestForeground();
		app.pushGlobalScreen(this, 0, UiEngine.GLOBAL_QUEUE);
		if (!Settings.isEnabled(Settings.ALLOW_SOUND_KEY)) {
			app.addKeyListener(listener);
			app.addMediaActionHandler(soundKeyCapturer);
		}
		if (Settings.isEnabled(Settings.PROXIMITY)) {
			app.getUiEngineInstance().addInputSettings(proximitySettings);
		}
		if (Settings.isEnabled(Settings.SHOW_BATTERY)) {
			add(batteryGauge);
		}
		add(dateTimeField);
		locked = true;
	}

	public synchronized void unlock() {
		if (!locked) {
			return;
		}
		DynamicIcon.removeAll();
		UiApplication app = UiApplication.getUiApplication();
		app.requestBackground();
		app.popScreen(this);
		app.removeKeyListener(listener);
		app.removeMediaActionHandler(soundKeyCapturer);
		app.getUiEngineInstance().removeInputSettings(proximitySettings);
		deleteAll();
		locked = false;
	}
}
